package com.ygqh.baby.dao.impl;

import com.alibaba.fastjson.JSON;
import com.mongodb.*;
import com.mongodb.AggregationOptions.OutputMode;
import com.ygqh.baby.ao.DataStatus;
import com.ygqh.baby.ao.QueryInfo;
import com.ygqh.baby.dao.ChatRecordDao;
import com.ygqh.baby.model.ChatRecord;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository
public class ChatRecordDaoImpl extends BaseMongodbDaoImpl<ChatRecord> implements ChatRecordDao {

	@Override
	public List<Map<String, Object>> report(QueryInfo queryInfo) {
		List<DBObject> list = report();
		// sort
		DBObject sortFields = new BasicDBObject("_id", -1);
		DBObject sort = new BasicDBObject("$sort", sortFields);
		// queyinfo
		DBObject skip = new BasicDBObject("$skip", queryInfo.getStart());
		DBObject limit = new BasicDBObject("$limit", queryInfo.getLimit());
		// aggregate
		list.add(sort);
		list.add(skip);
		list.add(limit);
		logger.info("[ChatRecordDaoImpl][report][pipeline]: " + JSON.toJSONString(list));
		AggregationOptions options = AggregationOptions.builder().outputMode(OutputMode.CURSOR).build();
		Cursor cursor = super.getMongoTemplate().getCollection("YG_CHAT_RECORD").aggregate(list, options);
		
		List<Map<String, Object>> dataList = new ArrayList<>();
		while (cursor.hasNext()) {
			DBObject dbObject = cursor.next();
			Map<String, Object> data = new HashMap<>();
			data.put("date", dbObject.get("_id"));
			data.put("count", dbObject.get("count"));
			dataList.add(data);
        }
		return dataList;
	}
	
	private List<DBObject> report() {
		List<DBObject> list = new ArrayList<>();

		/*
		 * match1
 		 */
		list.add(new BasicDBObject("$match", new BasicDBObject("status", DataStatus.Valid.name())));

		/*
		 * project1
		 */
		DBObject project1Fields = new BasicDBObject();
		// userId
		BasicDBList userIdSubstr = new BasicDBList();
		userIdSubstr.add("$userId");
		userIdSubstr.add(0);
		userIdSubstr.add(10);
		DBObject userIdSubstrField = new BasicDBObject("$substr", userIdSubstr);
		project1Fields.put("userId", userIdSubstrField);

		// receiveUserId
		project1Fields.put("receiveUserId", "$receiveUserId");

		// createTime
		// createTime加8小时
		DBObject addField = new BasicDBObject();
		BasicDBList add = new BasicDBList();
		add.add("$createTime");
		add.add(8 * 60 * 60 * 1000);
		addField.put("$add", add);
		// createTime截取到日期
		BasicDBList substr = new BasicDBList();
		substr.add(addField);
		substr.add(0);
		substr.add(10);
		DBObject substrField = new BasicDBObject("$substr", substr);
		project1Fields.put("createTime", substrField);

		list.add(new BasicDBObject("$project", project1Fields));

		/*
		* project2
		*/
		DBObject project2Fields = new BasicDBObject();
		project2Fields.put("userId", "$userId");
		project2Fields.put("receiveUserId", "$receiveUserId");
		project2Fields.put("createTime", "$createTime");
		// 比较userId和receiveUserId是否值相等diff
		DBObject eqField = new BasicDBObject();
		BasicDBList eq = new BasicDBList();
		eq.add("$userId");
		eq.add("$receiveUserId");
		eqField.put("$eq", eq);
		project2Fields.put("diff", eqField);
		list.add(new BasicDBObject("$project", project2Fields));

		/*
		 * match2
		 */
		list.add(new BasicDBObject("$match", new BasicDBObject("diff", true)));

		/*
		 * group1
		 */
		DBObject idField1 = new BasicDBObject("userId", "$userId");
		idField1.put("createTime", "$createTime");
		list.add(new BasicDBObject("$group", new BasicDBObject("_id", idField1)));

		// group2
		DBObject countField = new BasicDBObject("$sum", 1);
		DBObject groupFields2 = new BasicDBObject("_id", "$_id.createTime");
		groupFields2.put("count", countField);
		list.add(new BasicDBObject("$group", groupFields2));

		return list;
	}

	@Override
	public Long countReport() {
		List<DBObject> list = report();
		DBObject count_field = new BasicDBObject("$sum", 1);
		DBObject groupFields = new BasicDBObject("_id", "");
		groupFields.put("count", count_field);
		DBObject group = new BasicDBObject("$group", groupFields);
		list.add(group);
		Long count = 0L;
		logger.info("[ChatRecordDaoImpl][countReport][pipeline]: " + JSON.toJSONString(list));
		AggregationOptions options = AggregationOptions.builder().outputMode(OutputMode.CURSOR).build();
		Cursor cursor = super.getMongoTemplate().getCollection("YG_CHAT_RECORD").aggregate(list, options);
		while (cursor.hasNext()) {
			DBObject dbObject = cursor.next();
			count += Long.valueOf(dbObject.get("count").toString());
        }
		return count;
	}

}
